/** 
 * 	 @file   heater.c
 *   @author M. P. Hayes, UCECE
 *   @date   21 August 2007
 *   @brief  Heater driver
*/

/*
TODO:
- [ ] Make sure it behaves as expected
- [ ] Test using test class.
- [ ] Optimize Code
- [ ] Compile and test on board
*/
#include "config.h"
#include "port.h"
#include "heater.h" /** @see heater */

/** Physical Setup */
#define HEATER_PIN (1 << 5)
#define HEATER_PORT PORT_C

/** Private variables. */
static uint16_t frequency;		/* Which is the number of updates per second */
static uint8_t cycles;
static uint8_t cycles_on;
static uint8_t cycles_reqd;
static bool heater_on;

/** Private function stubs */
static void heater_start(void);
static void heater_stop(void);
static void heater_switch(void);


/** Set heater duty cycle.
@param percent duty cycle percent
@see heater_start()  
*/
void heater_set (uint8_t percent)
{
	cycles_on = frequency*percent/100;	/** This is set once. /*
	cycles_reqd = cycles_on;  /** Start with the on cycle*/
	heater_on = TRUE;
	heater_start();
}


/** Update heater.  */
void heater_update (void)
{
	/* Need to turn heater on and off appropriately.  */
	if(cycles >= cycles_reqd)
	{
		heater_switch();
	} else {
		cycles++;
	}
}


/** Initialise heater.
    @param update_rate update rate in Hz  */
void heater_init (uint16_t update_rate)
{
    /* Need to configure I/O port as output to drive MOSFET.  */
    port_pins_config_output(HEATER_PORT, HEATER_PIN);
	frequency = update_rate;
}


/** Changes heater from off to on or vice versa 
 * @see heater_start()
 * @see heater_stop()
 * */
static void heater_switch()
{
	cycles = 0;		//Reset cycles
	if(heater_on)
	{
			cycles_reqd = frequency - cycles_on;
			heater_on = FALSE;
			heater_stop();
	} else {
			cycles_reqd = cycles_on;
			heater_on = TRUE;
			heater_start();
	}
}

/** Start the actual heater device */
static void heater_start()
{
	port_pins_set_high(HEATER_PORT, HEATER_PIN);
}

/** Stop the actual heater device */
static void heater_stop()
{
	port_pins_set_low(HEATER_PORT, HEATER_PIN);
}
